﻿using System;
using System.Collections.Generic;
using System.Reflection;
using System.Text;
using Kugar.Core.ExtMethod;
using Kugar.Core.Web;
using Kugar.UI.Web.AdminLTE.Authentications;
using Kugar.UI.Web.AdminLTE.Filters;
using Kugar.UI.Web.AdminLTE.Interfaces;
using Kugar.UI.Web.AdminLTE.PageControls;
using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Authentication.Cookies;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc.Razor;
using Microsoft.AspNetCore.Routing;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.DependencyInjection.Extensions;
using Microsoft.Extensions.FileProviders;
using Microsoft.Extensions.Options;
using HttpContext = Kugar.Core.Web.HttpContext;

namespace Kugar.UI.Web.AdminLTE.Helpers
{
    public static class GlobalConfigurationHelper
    {
        internal static Dictionary<string,IAdminLoginManager> _cache=new Dictionary<string, IAdminLoginManager>(StringComparer.CurrentCultureIgnoreCase);

        /// <summary>
        /// 启用AdminLTEUI组件
        /// </summary>
        /// <param name="services"></param>
        public static void UseAdminLTE(this IServiceCollection services,bool registerOldAuthorize=true)
        {
            services.AddScoped(typeof(AdminLTEUI));

            var embeddedProvider = new EmbeddedFileProvider(typeof(AdminLTEElementBase).Assembly, "Kugar.UI.Web.AdminLTE");

            services.Configure<RazorViewEngineOptions>(options =>
            {
                options.FileProviders.Add(embeddedProvider);
            });

            if (registerOldAuthorize)
            {
                
                services.AddAuthorization(options =>
                    {
                        options.AddPolicy("AdminLteDefaultAdminCheck", policy =>
                            policy.Requirements.Add(new AdminAuthorityRequirement()));
                    })
                    ;
                services.AddSingleton<IAuthorizationHandler, AdminAuthorityPolicyHandler>();

            }
            else
            {
                services.AddScoped<IAdminLoginManager>(x =>
                {
                    if (HttpContext.Current.GetRouteData().Values.TryGetValue("authenticationType", out var scheme))
                    {
                        if (_cache.TryGetValue(scheme.ToStringEx(), out var handler))
                        {
                            return handler;
                        }
                    }

                    return null;

                });
            }
            


            services.AddDistributedMemoryCache();

            services.AddSession(options =>
            {
                // Set a short timeout for easy testing.
                options.Cookie.SecurePolicy = CookieSecurePolicy.SameAsRequest;
                options.Cookie.Name = ".NetEscapades.Session";
                options.IdleTimeout = TimeSpan.FromMinutes(15);
                options.Cookie.HttpOnly = false;
                options.CookiePath = "/";
                //options.Cookie.Expiration=TimeSpan.FromDays(15);
                options.Cookie.SameSite = SameSiteMode.None;

            });


        }

        /// <summary>
        /// 是否使用内嵌的静态资源
        /// </summary>
        /// <param name="app"></param>
        public static void UseAdminLTEStaticFile(this IApplicationBuilder app)
        {
            app.UseSession();

            var embeddedProvider = new EmbeddedFileProvider(typeof(AdminLTEElementBase).Assembly, "Kugar.UI.Web.AdminLTE");
            
            app.UseStaticFiles(new StaticFileOptions
                               {
                                   FileProvider = embeddedProvider,
                                   RequestPath = new PathString("/adminltebase"),
                                   OnPrepareResponse = (context) => {
                                       var headers = context.Context.Response.GetTypedHeaders();
                                       headers.CacheControl = new Microsoft.Net.Http.Headers.CacheControlHeaderValue
                                                              {
                                                                  Public = true,
                                                                  MaxAge = TimeSpan.FromDays(365),
                                                                  
                                                              }; 
                                    }
                               });


            //options.AddPolicy("Over21", policy => policy.Requirements.Add(new MinimumAgeRequirement(21)));
        }

        public static AuthenticationBuilder AddAdminLTECookie(this AuthenticationBuilder builder,
            string authenticationScheme,
            string displayName,
            Action<AdminLteAuthenticationOptions> configureOptions)
        {
            builder.Services.TryAddEnumerable(ServiceDescriptor.Singleton<IPostConfigureOptions<AdminLteAuthenticationOptions>, PostConfigureCookieAuthenticationOptions>());
            return builder.AddScheme<AdminLteAuthenticationOptions, AdminLteAuthenticationHandler>(authenticationScheme, displayName,option=>
            {
                option.SchemeName = authenticationScheme;
                configureOptions?.Invoke(option);
                _cache.Add(authenticationScheme, option.LoginManager);
            });
        }

        public static AuthenticationBuilder AddAdminLTECookie(this AuthenticationBuilder builder,
            string authenticationScheme,
            Action<AdminLteAuthenticationOptions> configureOptions=null)
        {
            builder.Services.TryAddEnumerable(ServiceDescriptor.Singleton<IPostConfigureOptions<AdminLteAuthenticationOptions>, PostConfigureCookieAuthenticationOptions>());
            return builder.AddScheme<AdminLteAuthenticationOptions, AdminLteAuthenticationHandler>(authenticationScheme, authenticationScheme, option =>
            {
                option.SchemeName = authenticationScheme;
                configureOptions?.Invoke(option);
                _cache.Add(authenticationScheme,option.LoginManager);

            });
        }

        public static AuthenticationBuilder AddAdminLTECookie(this AuthenticationBuilder builder,
            string authenticationScheme,IAdminLoginManager loginManager)
        {
            

            builder.Services.TryAddEnumerable(ServiceDescriptor.Singleton<IPostConfigureOptions<AdminLteAuthenticationOptions>, PostConfigureCookieAuthenticationOptions>());
            return builder.AddScheme<AdminLteAuthenticationOptions, AdminLteAuthenticationHandler>(authenticationScheme, authenticationScheme, option =>
            {
                option.SchemeName = authenticationScheme;
                option.LoginManager = loginManager;
                _cache.Add(authenticationScheme,loginManager);
            });
        }

        /// <summary>
        /// 注册一个默认的登录处理器,用于兼容老的代码
        /// </summary>
        /// <param name="builder"></param>
        /// <returns></returns>
        public static AuthenticationBuilder AddDefaultAdminLTECookie(this AuthenticationBuilder builder)
        {
            builder.Services.TryAddEnumerable(ServiceDescriptor.Singleton<IPostConfigureOptions<AdminLteAuthenticationOptions>, PostConfigureCookieAuthenticationOptions>());
            return builder.AddScheme<AdminLteAuthenticationOptions, AdminLteAuthenticationHandler>("default", "default", option =>
            {
                option.SchemeName = default;
            });
        }

 
    }
}
